package com.gopay.scheduler.manager.sms.impl;

import com.gopay.common.constants.sms.SmsMassEnum;
import com.gopay.common.cps.dao.sms.SmsMassContentDAO;
import com.gopay.common.cps.service.sms.SmsMassBaseService;
import com.gopay.common.domain.sms.SmsMass;
import com.gopay.common.domain.sms.SmsMassContent;
import com.gopay.common.util.FastJsonUtil;
import com.gopay.common.util.NamedThreadFactory;
import com.gopay.scheduler.common.CronSmsMassConstants;
import com.gopay.scheduler.manager.sms.SmsMassManager;
import com.gopay.scheduler.util.DateUtils;
import com.gopay.sms.client.GopaySMSHttpClient;
import com.gopay.sms.common.constants.SMSAppId;
import com.gopay.sms.common.domain.RequestVO;
import com.gopay.sms.common.domain.ResponseVO;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/*
 * Copyright (c) 2016. www.gopay.com.cn Inc.All rights reserved.
 * 文件名称 : SmsMassManagerImpl
 * 创建日期 : 17/7/12 11:11
 * Author  : baiyunpeng
 * 短信群发manager
 */
@Service
public class SmsMassManagerImpl implements SmsMassManager {
    private Logger logger = LoggerFactory.getLogger(this.getClass());
    private ExecutorService threadPool = Executors.newFixedThreadPool(5,new NamedThreadFactory("smsMassTask"));
    @Autowired
    private SmsMassBaseService smsMassBaseService;
    @Autowired
    private SmsMassContentDAO massContentDAO;

    private ResponseVO sendSmsMethod(String packgeId ,String phStr, String smsContent){
        if(StringUtils.isEmpty(phStr))return null;
        RequestVO req = new RequestVO();
        req.setAppId(SMSAppId._11006.value);
        req.setContent(smsContent);
        logger.info("短信群发开始==packgeId[{}]==内容为:"+ FastJsonUtil.toJSONString(req),packgeId);
        //不打印手机号码
        req.setMobile(phStr);
        ResponseVO responseVO = GopaySMSHttpClient.getInstance().createVerificationCode(req);
        logger.info("短信群发结束==packgeId[{}]==内容为:"+ FastJsonUtil.toJSONString(responseVO),packgeId);
        return responseVO;
    }

    @Override
    public void packageList(List<Object[]> willBeSendList, String smsId, String content,String source) {
        if(willBeSendList==null || willBeSendList.size()==0)return;
        List<SmsMass> smsMassList = new ArrayList<>();
        List<String> phoneNumList = new ArrayList<>();
        for (Object[] obj : willBeSendList){
            SmsMass smsMass = new SmsMass();
            smsMass.setSmsId(new BigDecimal(obj[0].toString()).longValue());
            smsMass.setPhoneNum(obj[1].toString());
            smsMass.setSmsContentId(smsId);
            smsMassList.add(smsMass);
            phoneNumList.add(smsMass.getPhoneNum());
        }
        SmsMassTask smsMassTask = new SmsMassTask(this,smsMassBaseService,smsMassList,source,content,smsId);
        threadPool.execute(smsMassTask);
    }

    @Override
    public boolean judgeTime2ExecuteUpd(SmsMassContent smsMassContent,String status,int time) {
        Integer hh = Integer.parseInt(DateUtils.format(new Date(), "HH"));
        Integer sendHH = Integer.parseInt(DateUtils.format(smsMassContent.getSendTime(), "HH"));
        if(hh - sendHH >= time){
            logger.info(String.format("短信序号为%s的短信定时任务发送当前时间{%s}超过定时发送时间{%s},发送时间超时{%s}不执行发送",smsMassContent.getSmsId()
                    ,DateUtils.format(new Date(), "yyyyMMddHHmmss"),DateUtils.format(smsMassContent.getSendTime(), "yyyyMMddHHmmss"),hh - sendHH));
            massContentDAO.updateMassSatus(status,smsMassContent.getSmsId());
            return true;
        }
        return false;
    }

    @Override
    public void updateBatchByKey(String packgeId,String phr,String content) {
        sendSmsMethod(packgeId,phr, content);
        //if(responseVO==null)throw new GopayException("短信packageId为"+packgeId+"的短信定时任务异常");
        // if(!"100".equals(responseVO.getStatusCode()))throw new GopayException(code,"短信packageId为"+packgeId+"的短信定时任务异常");
        //不管状态码的原因是,有次遇到sms项目里报文xml返回成功,但是其代码里没有正常处理xml导致异常,但是目标短信已经发出去了,如果以responseVO不为null,其状态100来断定成功,会导致重复发送
        smsMassBaseService.updateSmsStatusByPackgeId(SmsMassEnum.SEND_OVER.getValue(),packgeId);
    }
}
class SmsMassTask implements Runnable {
    private Logger logger = LoggerFactory.getLogger(this.getClass());
    private SmsMassManager smsMassManager;
    private SmsMassBaseService smsMassBaseService;
    private List<SmsMass> smsMassList;
    private String source;
    private String content;
    private String smsId;

    public SmsMassTask(Object... target) {
        this.smsMassManager = target[0] == null ? null : (SmsMassManager) target[0];
        this.smsMassBaseService = target[1] == null ? null : (SmsMassBaseService) target[1];
        this.smsMassList = target[2] == null ? null : (List<SmsMass>) target[2];
        this.source = target[3] == null ? null : (String) target[3];
        this.content = target[4] == null ? null : (String) target[4];
        this.smsId = target[5] == null ? null : (String) target[5];
    }

    @Override
    public void run() {
        logger.info("短信群发短信id[{}]线程开启",smsId);
        long startSw = System.currentTimeMillis();
        StringBuffer phstr = new StringBuffer();
        List<SmsMass> sendlist = new ArrayList<SmsMass>();
        int ep = 0;
        for(int point = 0; point < smsMassList.size(); point++){
            sendlist.add(smsMassList.get(point));
            phstr.append(smsMassList.get(point).getPhoneNum());
            if((point+1)%CronSmsMassConstants.SIZE == 0 || point == (smsMassList.size()-1)){
                String phr = phstr.toString();
                String pakgeId = "";
                if(CronSmsMassConstants.SMS_NORMAL.equals(source)) {
                    pakgeId = smsMassBaseService.updateBatchByKey(sendlist, SmsMassEnum.SEND_SENDING.getValue());
                    logger.info("短信群发短信id[{}],短信packgeId[{}]",smsId,pakgeId);
                }else {
                    pakgeId = smsMassBaseService.updateBatchByKey(sendlist,SmsMassEnum.SEND_EXCEPTION.getValue());
                    logger.info("短信群发补偿机制,短信id[{}],短信packgeId[{}]",smsId,pakgeId);
                }
                try {
                    smsMassManager.updateBatchByKey(pakgeId,phr,content);
                } catch (Exception e) {
                    if(CronSmsMassConstants.SMS_NORMAL.equals(source)){
                        ep++;
                        smsMassBaseService.updateSmsAndContentToFail(SmsMassEnum.SEND_SENDING.getValue(),pakgeId,smsId);
                        logger.error(String.format("短信群发短信id[{%s}],短信packageId为[{%s}]的短信异常,更新状态为进行中[3]",smsId,pakgeId),e);
                    }else {
                        logger.error(String.format("短信补偿packageId为[{%s}],短信id为[{%s}]的短信异常,根据业务场景不再继续进行补偿",pakgeId,smsId),e);
                    }
                }
                phstr.delete(0,phstr.length());
                sendlist= new ArrayList<SmsMass>();
                continue;
            }
            phstr.append(",");
        }
        if(ep==0){
            logger.info("短信群发短信id[{}]全部发送成功,更新状态为已发送",smsId);
            smsMassBaseService.updateMassSatus(SmsMassEnum.SEND_OVER.getValue(),smsId);
        }
        long stopSw = System.currentTimeMillis();
        logger.info("短信群发短信id[{}]线程执行完毕,耗时[{}]秒",smsId,((stopSw*1.0 - startSw) / 1000));
    }
}
